package com.ruoyi.common.tcp;

import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.utils.BytesUtils;
import io.netty.channel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyClient {

    private static Logger log = LoggerFactory.getLogger(NettyClient.class);

    public static Map<String, ChannelFuture> channels = null;

    static EventLoopGroup eventLoopGroup = new NioEventLoopGroup();


    /**
     * 初始化Bootstrap
     */
    public static final Bootstrap getBootstrap(EventLoopGroup group) {
        if (null == group) {
            group = eventLoopGroup;
        }
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new NettyClientHandler());
                    }
                });
        return bootstrap;
    }


    //二次重连
    public static final Map<String , ChannelFuture> twoGetChannel(List<Map<String,Object>> portHosts){

        eventLoopGroup.shutdownGracefully();

        eventLoopGroup = new NioEventLoopGroup();

        return getChannel(portHosts);
    }


    //   获取所有连接
    public static final Map<String , ChannelFuture> getChannel(List<Map<String,Object>> portHosts) {
        Map<String , ChannelFuture> result = new HashMap<>();
        Bootstrap bootstrap = getBootstrap(null);

        for (Map<String, Object> map : portHosts) {
            String host = String.valueOf(map.get("IP"));
            int port = Integer.valueOf(String.valueOf(map.get("PORT")));
            bootstrap.remoteAddress(host, port);
            //异步连接tcp服务端
            ChannelFuture future = bootstrap.connect().addListener((ChannelFuture futureListener) -> {
                if (futureListener.isSuccess()) {
                    Channel channel = futureListener.channel();
                    if (channel.isActive()) {
                        System.out.println("Channel is active");
                    } else {
                        System.out.println("Channel is not active");
                    }
                }
                if (!futureListener.isSuccess()) {
                    log.info("与"+host+":"+port+"连接失败!");                    //与设备的连接失败-推送mqtt主题
                }
            });
            result.put(host+":"+port, future);
        }
        return result;
    }

    //   获取所有连接
    public static final Map<String, ChannelFuture> connect(String host, int port) {
        Map<String, ChannelFuture> result = new HashMap<>();
        Bootstrap bootstrap = getBootstrap(null);
        bootstrap.remoteAddress(host, port);
        //异步连接tcp服务端
        ChannelFuture future = bootstrap.connect().addListener((ChannelFuture futureListener) -> {
            if (futureListener.isSuccess()) {
                Channel channel = futureListener.channel();
                if (channel.isActive()) {
                    System.out.println("Channel is active");
                } else {
                    System.out.println("Channel is not active");
                }
            }
            if (!futureListener.isSuccess()) {
                log.info("与"+host+":"+port+"连接失败!");                    //与设备的连接失败-推送mqtt主题
            }
        });
        result.put(host + ":" + port, future);
        return result;
    }

    //发送消息
    public static void sendMsg(ChannelFuture future, String msg){
        try {
            if (future != null && future.channel().isActive()) {

                Channel channel = future.channel();
                InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress();
                String host = ipSocket.getHostString();
                int port = ipSocket.getPort();
                System.out.println("向设备" + host+":"+port+"发送数据");
                //项目封装的util类
                byte[] msgbytes = BytesUtils.hexStringToBytes(msg);
                ByteBuf buf = Unpooled.buffer();
                buf.writeBytes(msgbytes);
                // 2.写数据
                future.channel().writeAndFlush(buf).sync();
            }else if(future != null && !future.channel().isActive()){
                //重新连接
                Channel channel = future.channel();
                InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress();
                String host = ipSocket.getHostString();
                int port = ipSocket.getPort();
                NettyClient.channels = NettyClient.connect(host, port);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
